package com.xx.java8.chapter4;

import com.xx.java8.domain.Dish;
import javafx.util.Pair;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class MainApp {
    public static void main(String[] args) {
        List<Dish> dishList = Arrays.asList(
                new Dish("pizza", true, 550, Dish.Type.OTHER),
                new Dish("pork", false, 800, Dish.Type.MEAT),
                new Dish("beef", false, 700, Dish.Type.MEAT),
                new Dish("chicken", false, 400, Dish.Type.MEAT),
                new Dish("french fries", true, 530, Dish.Type.OTHER),
                new Dish("rice", true, 350, Dish.Type.OTHER),
                new Dish("season fruit", true, 120, Dish.Type.OTHER),
                new Dish("prawns", false, 300, Dish.Type.FISH),
                new Dish("salmon", false, 450, Dish.Type.FISH));

        Integer vegetableCount = dishList.stream()
                .filter(d -> d.getType() == Dish.Type.OTHER)
                .map(d -> 1)
                .reduce(0, (a, b) -> a + b);
        System.out.println("vegetableCount: " + vegetableCount);

        List<String> lowCaloricDishesName = dishList.parallelStream()
                .filter(m -> m.getCalories() < 400)
                .sorted(Comparator.comparing(Dish::getCalories))
                .map(m -> m.getName())
                .collect(Collectors.toList());

        dishList.stream()
                .filter(d -> d.getCalories() >= 350)
                .findAny()
                .ifPresent(d -> System.out.println(d.getName()));

        System.out.println(lowCaloricDishesName);

        List<Integer> integers = Arrays.asList(1, 2, 1, 3, 9, 2, 4, 4, 5, 9, 2);
        integers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

//        Integer reduce = integers.stream().reduce(1, (a, b) -> a * b);
        Integer reduce = integers.stream().reduce(0, Integer::sum);
        System.out.println("reduce: " + reduce);

        Integer max = integers.parallelStream().reduce(0, Integer::max);// (a, b) -> a > b ? a : b
        System.out.println("max: " + max);


        List<String> words = Arrays.asList("Hello", "World", "Perfect", "Great", "Predicate");
//        words.stream().map(String::length).forEach(System.out::println);
        words.stream()
                .map(w -> new Pair(w, w.length()))
                .sorted(Comparator.comparingInt(o -> (int) o.getValue()))
                .forEach(h -> System.out.println(h));

        StringBuilder sb = new StringBuilder();
        words.stream().forEach(w -> sb.append(w));
        Arrays.stream(sb.toString().toLowerCase().split("")).distinct().forEach(s -> System.out.println(s));

        List<Object> objects = words.stream().flatMap((Function<String, Stream<?>>) s -> Arrays.stream(s.split(""))).distinct().collect(Collectors.toList());
        System.out.println(objects);

        Integer[] integers1 = new Integer[]{1, 2, 3, 4, 5};
        List<Integer> integers2 = Arrays.stream(integers1).map(i -> i * i).collect(Collectors.toList());
        System.out.println(integers2);

        Optional<Integer> first = Arrays.stream(integers1).filter(i -> i % 3 == 0).findFirst();
        System.out.println(first.get());

        Integer[] integers3 = new Integer[]{1, 2, 3};
        Integer[] integers4 = new Integer[]{3, 4};
        List<Integer[]> integers5 = Arrays.stream(integers3).flatMap(i -> Arrays.stream(integers4).map(j -> new Integer[]{i, j})).collect(Collectors.toList());
        integers5.forEach(i -> {

            System.out.println();
        });
    }
}
